Reactive Forms
Reactive Forms נותנים לנו אפשרות שליטה גדולה יותר וגמישות בבניית טפסים. מבנה הטופס מוגדר בתוך קובץ ה-ts.
- מגדירים את הטופס בתוך קובץ ה-ts.
- מוסיפים ולידציות.
- מחברים את הגדרת הטופס לטופס ב-html.
כדי להשתמש ב-reactive forms צריך לייבא אותם ל-app module.
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
הגדרת טופס Reactive Form
גם לקומפוננטה צריכים לייבא את רכיבי הטפסים.
import { FormGroup, FormControl } from '@angular/forms';
loginReactiveForm: FormGroup = new FormGroup({
user: new FormControl(''),
password: new FormControl(''),
});
אפשר גם לתת ערך ברירת מחדל לשדה בטופס.
category: new FormControl('Papers');
אחרי שמגדירים את הטופס צריך לחבר אותו לטופס בקובץ ה-html. נשתמש ב-ngSubmit כדי להגדיר את הפונקציה שתופעל בזמן שליחת הטופס.
<div class="container">
<h1 class="mb-4">Reactive forms</h1>
<form [formGroup]="loginReactiveForm" (ngSubmit)="loginUser()">
<input type="text" formControlName="user" placeholder="Enter name"/>
<br /><br />
<input type="password" formControlName="password" placeholder="Enter password"/>
<br /><br />
<button>Login</button>
</form>
</div>
את הפונקציה נפעיל מתוך ה-class.
loginUser() {
console.log(this.loginReactiveForm.value);
}
Form validation
כדי להשתמש בולידציות צריך לייבא אותן.
import { FormGroup, FormControl, Validators } from '@angular/forms';
loginReactiveForm = new FormGroup({
user: new FormControl('', [Validators.required]),
password: new FormControl('', [
Validators.required,
Validators.minLength(6),
]),
});
אפשר להשתמש בולידטורים שונים כמו: required, min, max, email, minLength, maxLength.
אם שדה לא עבר את הולידציה, נרצה לשנות את העיצוב שלו כך שהשגיאה תבלוט למשתמש.
input.ng-invalid.ng-touched{
…
}
כדי להראות את השגיאות נשתמש בפונקציית get לקבל את השדה של הטופס:
get user() {
return this.loginReactiveForm.get('user');
}
get password() {
return this.loginReactiveForm.get('password');
}
עכשיו אפשר להראות את השגיאות בטופס ה-html.
<form [formGroup]="loginReactiveForm" (ngSubmit)="loginUser()">
<input type="text" formControlName="user" placeholder="Enter name" />
<br /><br />
<div
class="alert alert-danger"
role="alert"
*ngIf="user && user.invalid && user.touched">
The user name is not valid.
</div>
<br />
<input
type="password"
formControlName="password"
placeholder="Enter password"/>
<br /><br />
<div
class="alert alert-danger"
role="alert"
*ngIf="password && password.invalid && password.touched">
The password is not valid.
</div>
<br />
<button [disabled]="loginReactiveForm.invalid">Login</button>
</form>
Form group
אפשר לקבץ כמה שדות אחת קבוצה אחת. מגדירים container לקבוצה ושמים בתוכו את השדות הרצויים.
<form [formGroup]="contactForm" (ngSubmit)="onContactSubmit()">
<div formGroupName="presonalDetails">
<input type="text" formControlName="firstName">
<input type="text" formControlName="lastName">
<input type="text" formControlName="email">
<span *ngIf="!contactForm.get('presonalDetails.email')">Enter a valid email.</span>
</div>
<input type="text" formControlName="message">
</form>
מבנה של טופס פשוט:
contactForm: FormGroup = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl(''),
message: new FormControl(''),
});
מבנה של טופס עם קבוצה.
contactForm: FormGroup = new FormGroup({
presonalDetails: new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl(''),
}),
message: new FormControl(''),
});
Form array
אפשר להוסיף מערכים לטופס באנגולר על ידי FormArray. נגדיר את subjects כמערך וכל פעם כשנוסף נושא בטופס נכניס אותו לתוך המערך.
contactForm: FormGroup = new FormGroup({
presonalDetails: new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl(''),
}),
message: new FormControl(''),
subjects: new FormArray([
new FormControl(null),
])
});
addSubject(){
(<FormArray>this.contactForm.get('subjects')).push(new FormControl(null));
}
<form [formGroup]="contactForm" (ngSubmit)="onContactSubmit()">
<div formGroupName="presonalDetails">
<input type="text" formControlName="firstName" />
<input type="text" formControlName="lastName" />
<input type="text" formControlName="email" />
<span *ngIf="!contactForm.get('presonalDetails.email')"
>Enter a valid email.</span
>
</div>
<input type="text" formControlName="message" />
<div formArrayName="subjects">
<ng-container
*ngFor="let subject of contactForm.get('subjects')['controls']; index as i"
>
<input type="text" placeholder="add subject..." formControlName="{{ i }}"/>
</ng-container>
<button (click)="addSubject()">Add subject</button>
</div>
</form>
אפשר ליצור ולידציות גם למערך.
(<FormArray>this.contactForm.get('subjects')).push(new FormControl(null, Validators.required));